﻿<template>
  <div class="app-container">
    <div
      class="filter-title"
      style="text-align: right;"
    >
      <el-form
        label-position="right"
        label-width="80px"
      >
        <el-button
          class="filter-item"
          style="margin-left: 10px;"
          type="primary"
          icon="el-icon-edit"
          @click="handleCreate"
        >{{ $t('table.add') }}</el-button>
      </el-form>
    </div>
    <el-table
      :data="tableListData"
      row-key="id"
      :row-style="toggleDisplayTr"
      border
      stripe
      class="init_table"
    >
      <el-table-column
        fixed="left"
        align="center"
        width="55"
        type="index"
        label="序号"
      ></el-table-column>
      <el-table-column
        label="权限名称"
        min-width="200"
        show-overflow-tooltip
        align="left"
      >
        <template slot-scope="scope">
          <p :style="`margin-left: ${scope.row.__level * 20}px;margin-top:0;margin-bottom:0`">
            <i
              class="permission_toggleFold"
              :class="toggleFoldingClass(scope.row)"
              @click="toggleFoldingStatus(scope.row)"
            ></i>
            {{ scope.row.title }}
          </p>
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        show-overflow-tooltip
        :label="$t('public.id')"
      >
        <template slot-scope="scope">
          <span>{{ scope.row.id }}</span>
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        show-overflow-tooltip
        :label="$t('menu.name')"
      >
        <template slot-scope="scope">
          <span>{{ scope.row.name }}</span>
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        show-overflow-tooltip
        :label="$t('menu.pid')"
      >
        <template slot-scope="scope">
          <span>{{ scope.row.pid }}</span>
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        show-overflow-tooltip
        :label="$t('menu.title')"
      >
        <template slot-scope="scope">
          <span>{{ scope.row.title }}</span>
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        show-overflow-tooltip
        :label="$t('menu.ismenu')"
      >
        <template slot-scope="scope">
          <span>{{ whetherEs(scope.row.ismenu) }}</span>
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        show-overflow-tooltip
        :label="$t('menu.weigh')"
      >
        <template slot-scope="scope">
          <span>{{ scope.row.weigh }}</span>
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        show-overflow-tooltip
        :label="$t('public.status')"
      >
        <template slot-scope="scope">
          <span :class="statusColor(scope.row.status)">{{ disableEs(scope.row.status) }}</span>
        </template>
      </el-table-column>
      <el-table-column
        fixed="right"
        align="center"
        :label="$t('table.actions')"
        :width="operWidth"
        class-name="small-padding fixed-width"
      >
        <template slot-scope="scope">
          <el-button
            type="primary"
            size="mini"
            @click="handleRead(scope.row)"
          >{{ $t('table.read') }}</el-button>
          <el-button
            type="primary"
            size="mini"
            @click="handleUpdate(scope.row)"
          >{{ $t('table.edit') }}</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 编辑 -->
    <el-dialog
      :title="textMap[dialogStatus]"
      :visible.sync="dialogFormVisible"
    >
      <el-form
        ref="dataForm"
        :rules="rules"
        :model="temp"
        label-position="right"
        label-width="35%"
        style="width: 400px margin-left:120px"
        size="small"
      >
        <el-form-item
          v-if="dialogStatus=='!create'"
          :label="$t('public.id')"
          prop="id"
        >
          <span>{{ temp.id }}</span>
        </el-form-item>
        <el-form-item
          :label="$t('menu.name')"
          prop="name"
        >
          <el-input v-model="temp.name"></el-input>
        </el-form-item>
        <el-form-item
          :label="$t('menu.icon')"
          prop="icon"
        >
          <el-input v-model="temp.icon"></el-input>
        </el-form-item>
        <el-form-item
          :label="$t('menu.pid')"
          prop="pid"
        >
          <el-input v-model="temp.pid"></el-input>
        </el-form-item>
        <el-form-item
          :label="$t('menu.title')"
          prop="title"
        >
          <el-input v-model="temp.title"></el-input>
        </el-form-item>
        <el-form-item
          :label="$t('menu.ismenu')"
          prop="ismenu"
        >
          <el-radio-group v-model="temp.ismenu">
            <el-radio :label="1">是</el-radio>
            <el-radio :label="0">否</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item
          :label="$t('menu.weigh')"
          prop="weigh"
        >
          <el-input v-model="temp.weigh"></el-input>
        </el-form-item>
        <el-form-item
          :label="$t('public.status')"
          prop="status"
        >
          <el-radio-group v-model="temp.status">
            <el-radio :label="1">正常</el-radio>
            <el-radio :label="2">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <div
        slot="footer"
        class="dialog-footer"
      >
        <el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
        <el-button
          v-if="dialogStatus=='create'"
          type="primary"
          :disabled="!createDisabled"
          @click="createData"
        >{{ $t('table.confirm') }}</el-button>
        <el-button
          v-else
          type="primary"
          :disabled="!updateDisabled"
          @click="updateData"
        >{{ $t('table.confirm') }}</el-button>
      </div>
    </el-dialog>
    <!-- 查看 -->
    <el-dialog
      :title="textMap[dialogStatus]"
      :visible.sync="dialogFormRead"
    >
      <el-form
        :model="temp"
        label-position="right"
        label-width="40%"
        style="width: 400px margin-left:120px"
        size="small"
      >
        <el-form-item :label="$t('public.id')">
          <span>{{ temp.id }}</span>
        </el-form-item>
        <el-form-item :label="$t('menu.name')">
          <span>{{ temp.name }}</span>
        </el-form-item>
        <el-form-item :label="$t('menu.pid')">
          <span>{{ temp.pid }}</span>
        </el-form-item>
        <el-form-item :label="$t('menu.title')">
          <span>{{ temp.title }}</span>
        </el-form-item>
        <el-form-item :label="$t('menu.ismenu')">
          <span>{{ whetherEs(temp.ismenu) }}</span>
        </el-form-item>
        <el-form-item :label="$t('menu.weigh')">
          <span>{{ temp.weigh }}</span>
        </el-form-item>
        <el-form-item :label="$t('public.status')">
          <span>{{ disableEs(temp.status) }}</span>
        </el-form-item>
      </el-form>
      <div
        slot="footer"
        class="dialog-footer"
      >
        <el-button @click="dialogFormRead = false">{{ $t('table.cancel') }}</el-button>
        <el-button
          type="primary"
          @click="dialogFormRead = false"
        >{{ $t('table.confirm') }}</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
// import waves from "@/directive/waves"; // 水波纹指令
import Vue from "vue";

let data = [];
export default {
  data: () => ({
    tableListData: [], // tableListData 展示数据的data
    foldList: [], // 该数组中的值 都会在列表中进行隐藏  死亡名单
    createDisabled: true,
    updateDisabled: true,
    dialogStatus: "",
    opreaterItem: 2,
    textMap: {
      update: "更新",
      create: "添加",
      review: "审核",
      read: "查看"
    },
    temp: {
      id: undefined,
      name: "",
      pid: "",
      title: "",
      ismenu: "",
      weigh: "",
      status: "",
      icon: ""
    },
    rules: {
      name: [{ required: true, message: "请输入菜单名称", trigger: "blur" }],
      pid: [{ required: true, message: "输入父id", trigger: "change" }],
      title: [{ required: true, message: "请填写标题", trigger: "change" }],
      ismenu: [
        { required: true, message: "请选择是否为菜单", trigger: "change" }
      ],
      weigh: [{ required: true, message: "请填写权重", trigger: "blur" }],
      coupon_url: [
        { required: true, message: "请填写优惠券链接", trigger: "blur" }
      ],
      status: [{ required: true, message: "请审核", trigger: "change" }]
    },
    dialogFormVisible: false,
    dialogFormRead: false
  }),
  computed: {
    /** *******************************
     ** Fn: foldAllList
     ** Intro: 记录属性结构的首层节点
     ** Author: zyx
     ******************************* **/
    foldAllList() {
      return this.tableListData.map(x => x.__identity);
    },
    operWidth: function() {
      return this.opreaterItem * 80 + "px";
    }
  },
  created() {
    this.getData();
  },
  methods: {
    /** *******************************
     ** Fn: toggleFoldingStatus
     ** Intro: 切换展开 还是折叠
     ** @params: params 当前点击行的数据
     ** Author: zyx
     ******************************* **/
    toggleFoldingStatus(params) {
      this.foldList.includes(params.__identity)
        ? this.foldList.splice(this.foldList.indexOf(params.__identity), 1)
        : this.foldList.push(params.__identity);
    },
    /** *******************************
     ** Fn: toggleDisplayTr
     ** Intro: 该方法会对每一行数据都做判断 如果foldList 列表中的元素 也存在与当前行的 __family列表中  则该行不展示
     ** @params:
     ** Author: zyx
     ******************************* **/
    toggleDisplayTr({ row, index }) {
      for (let i = 0; i < this.foldList.length; i++) {
        const item = this.foldList[i];
        // 如果foldList中元素存在于 row.__family中，则该行隐藏。  如果该行的自身标识等于隐藏元素，则代表该元素就是折叠点
        if (row.__family.includes(item) && row.__identity !== item) {
          return "display:none;";
        }
      }
      return "";
    },
    /** *******************************
     ** Fn: toggleFoldingClass
     ** Intro: 如果子集长度为0，则不返回字体图标。
     ** Intro: 如果子集长度为不为0，根据foldList是否存在当前节点的标识返回相应的折叠或展开图标
     ** Intro: 关于class说明：permission_placeholder返回一个占位符，具体查看class
     ** @params: params 当前行的数据对象
     ** Author: zyx
     ******************************* **/
    toggleFoldingClass(params) {
      return params.childrens
        ? this.foldList.indexOf(params.__identity) === -1
          ? "iconfont icon-minus-square-o"
          : "iconfont icon-plussquareo"
        : "permission_placeholder";
    },
    /** *******************************
     ** Fn: formatConversion
     ** Intro: 将树形接口数据扁平化
     ** @params: parent 为当前累计的数组  也是最后返回的数组
     ** @params: children 为当前节点仍需继续扁平子节点的数据
     ** @params: index 默认等于0， 用于在递归中进行累计叠加 用于层级标识
     ** @params: family 装有当前包含元素自身的所有父级 身份标识
     ** @params: elderIdentity 父级的  唯一身份标识
     ** Author: zyx
     ******************************* **/
    formatConversion(
      parent,
      childrens,
      index = 0,
      family = [],
      elderIdentity = "x"
    ) {
      // children如果长度等于0，则代表已经到了最低层
      // let page = (this.startPage - 1) * 10
      if (childrens) {
        if (childrens.length > 0) {
          childrens.map((x, i) => {
            // 设置 __level 标志位 用于展示区分层级
            Vue.set(x, "__level", index);
            // 设置 __family 为家族关系 为所有父级，包含本身在内
            Vue.set(x, "__family", [...family, elderIdentity + "_" + i]);
            // 本身的唯一标识  可以理解为个人的身份证咯 一定唯一。
            Vue.set(x, "__identity", elderIdentity + "_" + i);
            parent.push(x);
            // 如果仍有子集，则进行递归
            if (x.childrens) {
              if (x.childrens.length > 0) {
                this.formatConversion(
                  parent,
                  x.childrens,
                  index + 1,
                  [...family, elderIdentity + "_" + i],
                  elderIdentity + "_" + i
                );
              }
            }
          });
        }
      }
      return parent;
    },
    getData() {
      const authRuleIndexPath = {
        company: "STQ",
        api: "pc_AuthRule_index",
        version: "1.0",
        data: {}
      };
      this.socketApi.sendSock(JSON.stringify(authRuleIndexPath), res => {
        if (res) {
          this.socketData(res);
        }
      });
    },
    resetTemp() {
      this.temp = {
        id: undefined,
        name: "",
        pid: "",
        title: "",
        ismenu: "",
        weigh: "",
        status: "",
        icon: ""
      };
    },
    handleRefresh() {
      this.getData();
    },
    handleCreate() {
      this.resetTemp();
      this.dialogStatus = "create";
      this.dialogFormVisible = true;
      this.$nextTick(() => {
        this.$refs["dataForm"].clearValidate();
      });
    },
    handleRead(row) {
      // 打开查看弹窗
      this.temp = Object.assign({}, row); // copy obj
      this.dialogStatus = "read";
      this.dialogFormRead = true;
    },
    handleUpdate(row) {
      // 打开编辑弹窗
      this.temp = Object.assign({}, row); // copy obj
      this.dialogStatus = "update";
      this.dialogFormVisible = true;
      this.temp.status = parseInt(this.temp.status);
      this.$nextTick(() => {
        this.$refs["dataForm"].clearValidate();
      });
    },
    createData() {
      // 添加菜单
      this.$refs["dataForm"].validate(valid => {
        if (valid) {
          if (this.createDisabled) {
            this.createDisabled = false;

            const data = {
              name: this.temp.name,
              pid: this.temp.pid,
              title: this.temp.title,
              ismenu: this.temp.ismenu,
              weigh: this.temp.weigh,
              status: this.temp.status
            };
            if (this.temp.icon) {
              data["icon"] = this.temp.icon;
            }
            const authRuleEditPath = {
              company: "STQ",
              api: "pc_AuthRule_add",
              version: "1.0",
              data: data
            };
            this.socketApi.sendSock(JSON.stringify(authRuleEditPath), res => {
              if (res) {
                this.socketData(res);
              }
              setTimeout(() => {
                this.createDisabled = true;
              }, 1000);
            });
          }
        }
      });
    },
    updateData() {
      // 更新菜单
      this.$refs["dataForm"].validate(valid => {
        if (valid) {
          if (this.updateDisabled) {
            this.updateDisabled = false;

            const data = {
              id: this.temp.id,
              name: this.temp.name,
              pid: this.temp.pid,
              title: this.temp.title,
              ismenu: this.temp.ismenu,
              weigh: this.temp.weigh,
              status: this.temp.status,
              icon: this.temp.icon
            };

            const authRuleEditPath = {
              company: "STQ",
              api: "pc_AuthRule_edit",
              version: "1.0",
              data: data
            };
            this.socketApi.sendSock(JSON.stringify(authRuleEditPath), res => {
              if (res) {
                this.socketData(res);
              }
              setTimeout(() => {
                this.updateDisabled = true;
              }, 1000);
            });
          }
        }
      });
    },
    socketData(res) {
      if (res !== '{"type":"ping"}') {
        const resj = JSON.parse(res);
        if (resj.api === "pc_AuthRule_index") {
          if (resj.code === -1) {
            data = [];
            this.$message.error(resj.message);
          } else {
            data = resj.data;
          }
          data = JSON.parse(
            JSON.stringify(data).replace(/children/g, "childrens")
          );
          this.tableListData = this.formatConversion([], data);
        } else if (resj.api === "pc_AuthRule_add") {
          this.dialogFormVisible = false;
          this.getData();
          this.$notify({
            title: "成功",
            message: "添加成功",
            type: "success",
            duration: 2000
          });
        } else if (resj.api === "pc_AuthRule_edit") {
          if (resj.code === -1) {
            data = [];
            this.$message.error(resj.message);
          } else {
            this.dialogFormVisible = false;
            this.getData();
            this.$notify({
              title: "成功",
              message: "更新成功",
              type: "success",
              duration: 2000
            });
          }
        }
      }
    }
  }
};
</script>

<style scoped>
.permission_toggleFold {
  width: 20px;
  height: 20px;
  text-align: center;
  line-height: 20px;
  display: inline-block;
  position: relative;
}
.permission_toggleFold.iconfont.icon-minus-square-o:after {
  content: "-";
  color: #9e9e9e;
  font-size: 20px;
}
.permission_toggleFold.iconfont.icon-plussquareo:after {
  content: "+";
  color: #9e9e9e;
  font-size: 20px;
}
</style>
